moddbfandomcom-20200213-history
DirectX:DirectSound:Tutorials:VB:DX7:Loading Sound Buffers from Custom Resource Files
I hope there're no vegetarians among us today because I'm going to get straight to the meat! DirectSoundBuffer.WriteBuffer(start As Long, size As Long, buffer As Any, flags As CONST_DSBLOCKFLAGS) I wonder if anyone has ever bothered to look at this method of the DirectSoundBuffer object before. I know I certainly hadn't paid it any attention prior to now! But what a thing of beauty she is. All you do is indicate where to write within the buffer (start, usually at the beginning: zero), how much stuff you want to write (size) and what you want to write in that space (buffer). The buffer must be an array of bytes, but you pass only the first element of that array. There's also a flags variable to pass, which can be either DSBLOCK_FROMWRITECURSOR (which writes from the current position of the buffer's playback and ignores the start variable), or DSBLOCK_ENTIREBUFFER (which writes to the entire buffer and ignores the size variable). As great as WriteBuffer is, we're still not in the clear. We need some method of extracting the byte data from a wave file in order to pass it as our buffer variable, AND we also must find a way to fill a WAVEFORMATEX structure so that we can initialize the buffer correctly when we create it manually. How? Ryan's (not) patented wave file extractor! 'Wave file format info Private Type WAVETYPE strHead As String * 12 strFormatID As String * 4 lngChunkSize As Long intFormat As Integer intChannels As Integer lngSamplesPerSec As Long lngAvgBytesPerSec As Long intBlockAlign As Integer intBitsPerSample As Integer End Type Global gudtHeader As WAVETYPE Global glngChunkSize As Long Global gbytData() As Byte Sub ExtractWaveData(strFileName As String, lngOffset As Long) Dim intWAVFile As Integer Dim i As Long Dim strTemp As String * 4 Dim blnFound As Boolean 'Open the wave intWAVFile = FreeFile() Open strFileName For Binary Access Read Lock Write As intWAVFile 'Get the header info Get intWAVFile, lngOffset, gudtHeader 'Find the "data" portion of the file For i = lngOffset To LOF(intWAVFile) Get intWAVFile, i, strTemp If strTemp = "data" Then blnFound = True Exit For End If Next i 'Ensure this is a wave file If blnFound = False Then MsgBox "Invalid wave data.", vbCritical, "Invalid Wave" Close intWAVFile Exit Sub End If 'Get the data information Get intWAVFile, , glngChunkSize ReDim gbytData(glngChunkSize) Get intWAVFile, , gbytData Close intWAVFile End Sub This gives us everything we need! We now have the wave data buffer (gbytData) and know its size (glngChunkSize). Also, gudtHeader contains the essential info we need for filling a WAVEFORMATEX structure and initializing a buffer from scratch! Observe: Public Sub LoadSound(objBuffer As DirectSoundBuffer) Dim udtBufferDesc As DSBUFFERDESC Dim udtFormat As WAVEFORMATEX 'Set the Wave Format With udtFormat .nFormatTag = gudtHeader.intFormat .nChannels = gudtHeader.intChannels .lSamplesPerSec = gudtHeader.lngSamplesPerSec .nBitsPerSample = gudtHeader.intBitsPerSample .nBlockAlign = gudtHeader.intBlockAlign .lAvgBytesPerSec = gudtHeader.lngAvgBytesPerSec End With 'Create the buffer udtBufferDesc.lBufferBytes = glngChunkSize Set objBuffer = mobjDS.CreateSoundBuffer(udtBufferDesc, udtFormat) 'Load the buffer with data objBuffer.WriteBuffer 0, glngChunkSize, gbytData(0), DSBLOCK_ENTIREBUFFER End Sub After extracting the wave data from a file we can run this LoadSound routine to create a buffer and load it properly. I realize this tutorial is quite advanced and hope this sample source code may serve to clarify somewhat. Category:VB Category:Tutorial Category:DirectX Category:DirectSound